Skip to content

Bundle dependency updates, harden Dependabot reviews#207

Merged
lelia merged 8 commits into
mainfrom
lelia/bundle-deps-harden-dependabot
May 29, 2026
Merged

Bundle dependency updates, harden Dependabot reviews#207
lelia merged 8 commits into
mainfrom
lelia/bundle-deps-harden-dependabot

Conversation

@lelia
Copy link
Copy Markdown
Contributor

@lelia lelia commented May 29, 2026

Summary

A maintenance-focused PR with two threads:

  1. Bundle dependency updates — twelve outstanding Dependabot PRs (nine main-app uv deps + three e2e fixture manifests), all verified through Socket Firewall (sfw) before bundling. idna 3.11 → 3.15 is security-motivated — pulls in the fix for CVE-2026-45409 (a quadratic-time DoS that bypassed the earlier CVE-2024-3651 mitigation); the rest are version-currentness hygiene.
  2. Harden Dependabot review — the repo had no explicit dependabot.yml (hence the pileup). Adds grouped/cooldowned Dependabot config, a dependabot-review workflow that runs anonymous Socket Firewall smoke jobs on every Dependabot PR (no API secret required), and lock-drift / import-smoke / pip-audit guards to python-tests.

Dependencies (closes 12 Dependabot PRs)

PR Package Bump Notes
#205 idna 3.11 → 3.15 CVE-2026-45409 fix
#210 uv 0.9.21 → 0.11.17 latest (Dependabot targeted 0.11.15)
#200 urllib3 2.6.3 → 2.7.0
#198 gitpython 3.1.46 → 3.1.50
#190 python-dotenv 1.2.1 → 1.2.2
#188 pytest 9.0.2 → 9.0.3
#181 cryptography 46.0.5 → 46.0.7
#177 pygments 2.19.2 → 2.20.0
#175 requests 2.32.5 → 2.33.0
#209 axios (e2e/simple-npm) 1.15.0 → 1.16.1 latest (Dependabot targeted 1.16.0)
#187 requests (e2e/simple-pypi) 2.31.0 → 2.33.0
#186 flask (e2e/simple-pypi) 3.0.0 → 3.1.3

All twelve final versions installed clean through sfw (Socket Firewall Free) across the full transitive tree.

Dependabot review hardening

  • .github/dependabot.yml (new). Groups Python minor/patch into a weekly PR plus a separate major-update PR; groups GitHub Actions; tracks Docker separately; 7-day cooldown. The e2e fixtures under tests/e2e/fixtures/ are excluded by omission (no ecosystem registered against those paths) — fixture pins should be chosen for supply-chain signal, not auto-rolled. Pattern adapted from SocketDev/socket-basics.
  • .github/workflows/dependabot-review.yml (new). On every Dependabot PR: inspect changed files, then conditionally run Socket Firewall (sfw) install smoke jobs against the affected manifests. sfw uses the anonymous Socket public-data path — no API key, so this runs under the standard pull_request context with no pull_request_target and no token-leak surface. The key property that makes it safe for fork / Dependabot / external-contributor PRs.
  • python-tests.yml gains: uv lock --locked drift check, top-level import smoke (catches API-removal breaks from upgraded deps), and pip-audit on the locked deps.
  • e2e-test.yml now skips on Dependabot PRs (no SOCKET_CLI_API_TOKEN access); the sfw smoke jobs cover the supply-chain check without the secret.

Housekeeping

  • .gitignore reorganized into labeled, sorted sections; added .context/, coverage.xml, .pytest_cache/, vim swap files. Dropped a stray `*.cpython-312.pyc`` line with a literal-backtick typo.
  • Backfilled missing CHANGELOG entries for 2.2.81, 2.2.85, 2.2.86, 2.2.88, 2.2.89, 2.2.91, and 2.2.92.

Test plan

Automated (local, all green):

  • Full unit + core suite — 242 passed, 2 pre-existing skips
  • uv lock --locked drift check
  • Top-level import smoke across upgraded packages
  • Socket Firewall install path for all final dependency versions

Pending on the PR:

  • CI: python-tests + e2e-test + dependabot-review workflows

@lelia lelia requested a review from a team as a code owner May 29, 2026 02:37
@socket-security-staging
Copy link
Copy Markdown

socket-security-staging Bot commented May 29, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedpypi/​pytest@​9.0.2 ⏵ 9.0.387 +1100 +2100100100
Updatedpypi/​gitpython@​3.1.46 ⏵ 3.1.5093100 +50100100100
Updatedpypi/​python-dotenv@​1.2.1 ⏵ 1.2.299 +1100 +2100100100
Updatedpypi/​requests@​2.32.5 ⏵ 2.33.099 +1100 +2100100100
Updatedpypi/​uv@​0.9.21 ⏵ 0.11.17100 +1100 +3100100100

View full report

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 29, 2026

🚀 Preview package published!

Install with:

pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple socketsecurity==2.2.93.dev4

Docker image: socketdev/cli:pr-207

@socket-security
Copy link
Copy Markdown

socket-security Bot commented May 29, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedpypi/​pytest@​9.0.2 ⏵ 9.0.387 +1100 +2100100100
Updatedpypi/​gitpython@​3.1.46 ⏵ 3.1.5093100 +50100100100
Updatedpypi/​python-dotenv@​1.2.1 ⏵ 1.2.299 +1100 +2100100100
Updatedpypi/​requests@​2.32.5 ⏵ 2.33.099 +1100 +2100100100
Updatedpypi/​uv@​0.9.21 ⏵ 0.11.17100 +1100 +3100100100

View full report

lelia added 3 commits May 29, 2026 17:14
Reorganizes .gitignore into labeled sections (Python cache, venvs, build
artifacts, IDE, OS, logs, env files, generated output, project scratch,
Conductor) with sorted entries within each group and trailing slashes on
directory patterns for clarity.

Folds in three smaller intents that would otherwise be separate commits:
- Add .context/ for Conductor workspaces (collaboration scratch)
- Add coverage.xml + .pytest_cache/ to fully cover pytest-cov outputs
  (.coverage.* and htmlcov/ were already on main from prior work)
- Add *.swp / *.swo for vim swap files

Drops the stale `*.cpython-312.pyc\`` line with a literal-backtick typo;
it wasn't matching anything and `*.pyc` already covers the case.

No behavior changes anyone would notice from the resulting rule set.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>
The repo had no explicit Dependabot config, so Dependabot ran on full
defaults: one PR per package per manifest, across every manifest in
the tree -- including the e2e test fixtures that are intentionally
crafted to exercise Socket's scanner. The cumulative result was the
"PR pileup" this PR is consolidating.

New config:
- uv ecosystem (main app): grouped weekly into ONE minor/patch PR and
  one major PR; matches the existing python:uv labeling
- github-actions: grouped weekly into ONE minor/patch PR
- docker: separate weekly PR per Dockerfile change
- 7-day cooldown across all ecosystems to give upstream time to pull
  bad releases
- e2e fixtures (tests/e2e/fixtures/{simple-npm,simple-pypi}) are
  INTENTIONALLY excluded -- their pins should be chosen for supply-
  chain signal, not auto-bumped (this is why we had three fixture
  PRs in the cleanup)

Pattern adapted from SocketDev/socket-basics.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>
For every Dependabot-authored PR, inspect what changed and conditionally
run Socket Firewall (sfw) install smoke jobs against the affected
manifests. Because sfw uses the anonymous Socket public-data API it
needs NO secret, so this runs cleanly under the standard `pull_request`
context -- no pull_request_target, no token-leak surface.

Jobs (all conditional on file diff):
- python-sfw-smoke:      pyproject.toml / uv.lock -> `sfw uv sync` plus
                         an import smoke on the modules that depend on
                         the upgraded packages (cryptography, gitpython,
                         requests, ...). Catches API-removal breaks
                         from minor/patch deprecations.
- fixture-npm-sfw-smoke: tests/e2e/fixtures/simple-npm/** -> `sfw npm
                         install` in a clean cwd.
- fixture-pypi-sfw-smoke: tests/e2e/fixtures/simple-pypi/** -> `sfw pip
                         install -r requirements.txt` in a clean venv.
- dockerfile-smoke:      `docker build --pull` (no push) when the
                         Dockerfile changes.
- workflow-notice:       Flag Dependabot PRs that touch workflow or
                         dependabot config files for explicit human
                         review (anti-supply-chain-confusion guardrail).

Pattern adapted from SocketDev/socket-basics dependabot-review.yml.
Action SHAs match the pins already in python-tests.yml and e2e-test.yml
so zizmor stays happy.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>
@lelia lelia force-pushed the lelia/bundle-deps-harden-dependabot branch from 8717be9 to 4663c2a Compare May 29, 2026 21:17
Copy link
Copy Markdown
Collaborator

@flowstate Eric Hibbs (flowstate) left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, will re-review if the unit test fixes involve real changes

lelia added 4 commits May 29, 2026 17:42
python-tests.yml:
- `uv lock --locked` -- fails if uv.lock has drifted from pyproject.toml.
  Prevents the "forgot to commit the lockfile" class of mistake.
- Import smoke step that loads every top-level module touching the
  upgraded packages (cryptography, gitpython, requests, urllib3, ...).
  Catches API-removal breaks from minor/patch deprecations that the
  unit suite alone wouldn't surface.
- `uvx pip-audit --strict` against the synced env -- light CVE check
  on the resolved transitive tree. Runs in seconds via uv's caching.

e2e-test.yml:
- Skip e2e on Dependabot PRs. They don't have access to the Socket API
  secret so e2e would always fail on them, polluting the PR check UI.
  Supply-chain risk for dep bumps is covered by dependabot-review.yml's
  Socket Firewall smoke jobs, which need no secrets.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>
`uvx pip-audit --disable-pip` requires `-r` plus either hashed
requirements or `--no-deps`. The previous invocation crashed at start.

Now: export the locked deps via `uv export --no-hashes --no-emit-project`
into a tmp requirements file (skipping the local editable install of
the project itself), then feed that to pip-audit with `--disable-pip
--no-deps`. Verified locally -- no known vulnerabilities found across
the 85 locked transitive deps.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>
Bundles the nine open Dependabot PRs against the main app into a single
uv.lock regeneration. Where Dependabot's target trailed the latest published
release, we went to the current latest and re-verified through sfw:

- urllib3       2.6.3   -> 2.7.0     (closes #200)
- gitpython     3.1.46  -> 3.1.50    (closes #198)
- python-dotenv 1.2.1   -> 1.2.2     (closes #190)
- pytest        9.0.2   -> 9.0.3     (closes #188)
- uv            0.9.21  -> 0.11.17   (closes #210; Dependabot targeted 0.11.15)
- cryptography  46.0.5  -> 46.0.7    (closes #181)
- pygments      2.19.2  -> 2.20.0    (closes #177)
- requests      2.32.5  -> 2.33.0    (closes #175)
- idna          3.11    -> 3.15      (closes #205, CVE-2026-45409)

idna 3.14 fixed CVE-2026-45409 -- a quadratic-time DoS via oversized inputs
that bypassed the earlier CVE-2024-3651 mitigation. The rest are hygiene.

All nine final versions verified clean through Socket Firewall (sfw) on the
full transitive tree.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>
Closes the open Dependabot PRs against the e2e test fixtures. axios went to
the current latest (1.16.1) rather than Dependabot's 1.16.0 target:

- tests/e2e/fixtures/simple-npm:  axios    1.15.0 -> 1.16.1  (closes #209)
- tests/e2e/fixtures/simple-pypi: requests 2.31.0 -> 2.33.0  (closes #187)
- tests/e2e/fixtures/simple-pypi: flask    3.0.0  -> 3.1.3   (closes #186)

These fixtures were stale rather than intentionally pinned. Socket Firewall
verified the install paths. The new .github/dependabot.yml intentionally
excludes tests/e2e/fixtures/** from future auto-bumps.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>
@lelia lelia force-pushed the lelia/bundle-deps-harden-dependabot branch 2 times, most recently from b3c92a0 to f21851f Compare May 29, 2026 21:43
Patch release. Scope is maintenance only: dependency bundle + Dependabot
review hardening + housekeeping + CHANGELOG backfill. No behavior changes.

Targets 2.2.93 (not 2.2.92) to stay ahead of an in-flight 2.2.92 bug-fix
release landing separately.

CHANGELOG: 2.2.93 entry for this PR, plus backfilled entries for 2.2.81,
2.2.85, 2.2.86, 2.2.88, 2.2.89, and 2.2.91 (the #180 backfill covered
2.2.74-2.2.80; main reached 2.2.91 via #199 without a CHANGELOG note).

Version refs synced across pyproject.toml, socketsecurity/__init__.py, and
uv.lock per the version-incrementation CI check.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>
@lelia lelia force-pushed the lelia/bundle-deps-harden-dependabot branch from f21851f to 0df3247 Compare May 29, 2026 21:52
@lelia lelia merged commit 6969361 into main May 29, 2026
21 checks passed
lelia added a commit that referenced this pull request May 29, 2026
…xit-handling

Resolve conflicts:
- pyproject.toml / __init__.py / uv.lock: keep 2.3.0 (supersedes main's 2.2.93)
- CHANGELOG.md: keep both — 2.3.0 on top, then 2.2.93/2.2.92/2.2.91 from main
Dependency bumps from #207 (idna 3.15, urllib3, etc.) carried through;
uv lock --check passes.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>
lelia added a commit that referenced this pull request Jun 2, 2026
* ci: skip PR Preview and Version Check on Dependabot PRs

Both workflows failed on every Dependabot PR for reasons that don't apply to
dependency bumps:

- PR Preview publishes a dev build to Test PyPI + Docker Hub. On a dependency
  bump there's no version change, so the publish 400s ("File already exists")
  -- and it needs publish secrets a Dependabot PR shouldn't carry anyway.
- Version Check requires an incremented app version, but Dependabot PRs touch
  uv.lock / pyproject.toml without bumping socketsecurity's version, so the
  check always fails.

Add a job-level `if` to skip each on `dependabot[bot]`-authored PRs (same
pattern already used for e2e-test.yml). Job-level skips report as "skipped"
rather than blocking, and these stay required for human-authored PRs.

Follow-up to #207 (the Dependabot review hardening), addressing fallout
observed once that config went live on real Dependabot PRs.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>

* ci: pin sfw uv sync to the locked dependency set on Dependabot review

`sfw uv sync` is the intended way to route uv through Socket Firewall (per
Socket's own uv-wrapper guidance), so the python-sfw-smoke job was already
exercising the firewall -- uv's integration is just quieter than npm/pip
(no "N packages fetched" footer), which made it look like a no-op.

Add `--locked` so the check verifies the exact uv.lock set and fails on
lockfile drift instead of silently re-resolving to newer versions than the
PR locked. This makes the firewall inspect precisely what would be installed
and aligns with the deterministic-verification guidance for uv-based repos.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>

* ci: use official socketdev/action for Socket Firewall setup

Replace the hand-rolled `npm install -g sfw` in all three sfw smoke jobs with
the official setup action (socketdev/action@v1.3.2, mode: firewall-free).

Why:
- It's the documented GitHub Actions integration for Socket Firewall Free and
  wires up sfw routing correctly, rather than relying on an ad-hoc global npm
  install. This is the right mitigation for the class of Wrapper-Mode routing
  gaps where sfw can fail to proxy fetches from files.pythonhosted.org
  (tracked upstream as ENG-4871) -- exactly the "no interception" symptom that
  made the python job look like a no-op.
- The Python jobs no longer need actions/setup-node at all (the action
  provides sfw directly), so those steps are dropped; the npm fixture job keeps
  setup-node since `npm install` needs it.

Setup mode is firewall-free (anonymous, no API token) -- unchanged, and the
reason this is safe to run on Dependabot/untrusted PRs.

Our setup is Wrapper Mode + free edition + no CodeArtifact, so the Registry
Mode + CodeArtifact `uv sync`/`uv lock` issue (CE-171) does not apply.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>

* ci: factor Socket Firewall setup into a composite action

The three sfw smoke jobs (python / npm-fixture / pypi-fixture) repeated the
same setup: toolchain bootstrap + socketdev/action install. GitHub Actions
doesn't support YAML anchors, so extract the shared setup into a local
composite action instead.

- New .github/actions/setup-sfw: optional Python/Node/uv toolchain inputs +
  the socketdev/action (firewall-free) install.
- Each job now just declares the toolchain it needs (`uv`, `node`, or
  `python`) and runs its own distinct sfw command.

Net effect: the pinned socketdev/action SHA now lives in ONE place (future
bumps touch a single line), the per-job setup-python/setup-node duplication
is gone, and each job body is reduced to its actual firewall check. No
behavior change.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>

* ci: speed up and de-duplicate the release & preview pipelines

Performance (PR preview, the iterative-feedback path):
- Add a concurrency group with cancel-in-progress so pushing a PR again
  cancels the superseded (slow) preview run instead of letting it churn.
- Build preview images amd64-only. arm64 under QEMU emulation was the
  slowest part of the job, and preview images are for quick testing;
  release/stable keep multi-arch.
- Enable GitHub Actions Docker layer cache (type=gha) on all image builds
  so unchanged layers are reused across runs.

De-duplication (GitHub Actions has no YAML anchors, so use composite actions):
- New .github/actions/setup-docker-publish: the QEMU + Buildx + Docker Hub
  login trio, shared by release.yml, pr-preview.yml, and docker-stable.yml.
  These had drifted to three different pinned SHA sets; now there is one.
  (Docker Hub creds are passed as inputs since composite actions can't read
  secrets directly.)
- New .github/actions/setup-hatch: the pinned virtualenv/hatchling/hatch
  install shared by release.yml and pr-preview.yml.

No behavior change to what gets published; only how the pipelines are
assembled and how fast/parallel they run.

Stacked on #217 (lelia/fix-dependabot-checks) to avoid a pr-preview.yml
conflict with that PR's Dependabot skip; rebase onto main once #217 lands.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>

* ci: pin all GitHub Actions to latest release SHAs with version comments

Bump every third-party action to its latest git-tagged release, pinned to
the resolved commit SHA with a trailing '# vX.Y.Z' comment for readability:

  actions/checkout              -> v6.0.2
  actions/setup-python          -> v6.2.0
  actions/setup-node            -> v6.4.0
  actions/github-script         -> v9.0.0
  pypa/gh-action-pypi-publish   -> v1.14.0
  docker/setup-qemu-action      -> v4.1.0
  docker/setup-buildx-action    -> v4.1.0
  docker/login-action           -> v4.2.0
  docker/build-push-action      -> v7.2.0
  socketdev/action              -> v1.3.2 (comment only)

Applied across the setup-sfw composite action and all workflows, including
docker-stable.yml which previously used floating major-version comments.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>

* Keep dependabot action pins visible

* Configure Dependabot for composite actions

* Include composite actions in Dependabot review notice

* Rename Docker setup composite action

* Extend dependency review to maintainer PRs

* Use CLI Socket token for enterprise dependency review

* Restrict enterprise SFW to org members

* Use dedicated SFW token secret

* Use environment-scoped SFW token

* Gate enterprise SFW on non-fork PRs

* ci(dependency-review): bundle SFW reports as artifacts

Collect each Socket Firewall smoke job's output into an sfw-artifacts/
directory and upload it (if: always(), so the report survives even when
sfw BLOCKS an install):

  - context.txt   -- provenance (mode, manifest, PR#, head SHA)
  - sfw-*.log      -- teed firewall console output (pipefail preserves the
                      sfw exit code so a block still fails the job)
  - import-smoke.log (python jobs)
  - sfw-report.json -- the structured firewall report, copied from
                       $SFW_JSON_REPORT_PATH (the path socketdev/action
                       exports); a sfw-report-missing.txt breadcrumb is
                       written instead when no report is produced

Copy rather than redirect the JSON: socketdev/action's post step reads
$SFW_JSON_REPORT_PATH to render its job summary, so the report must stay
at its temp path. Artifacts are named per edition+manifest to stay unique
within a run. Pins actions/upload-artifact to v7.0.1.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>

---------

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants